<template>
  <div>
    <bpmn-model
        v-if="dataExit"
        :xml="xml"
        :category="category"
        :draftId="draftId"
        :is-view="false"
        @save="save"
        @showXML="showXML"
        @showJSON="showJSON"
    ></bpmn-model>
    <!--在线查看xml-->
    <el-dialog v-model="viewOpen" width="80%" top="5vh" append-to-body class="scrollbar">
      <template #header>
          <el-link type="primary" :underline="false" icon="DocumentCopy" v-copyText="viewData" v-copyText:callback="copyTextSuccess">&nbsp;复制</el-link>
      </template>
      <el-scrollbar>
        <pre v-highlight="viewData"><code :class="viewClass"></code></pre>
      </el-scrollbar>
    </el-dialog>
  </div>
</template>

<script setup name="FlowModel">
import { readXml, roleList, saveXml, userList, expList, deptList, postList, formList } from "@/api/flowable/definition";
import {buttonList} from "@/api/flowable/button";
import BpmnModel from '@/components/Process'
import vkBeautify from 'vkbeautify'
import hljs from 'highlight.js'
import 'highlight.js/styles/stackoverflow-dark.min.css'
import useModelerStore from '@/store/modules/modeler'
import {markRaw} from "@vue/reactivity";
const modelerStore = useModelerStore()
const route = useRoute();
import useAppStore from '@/store/modules/app'
const appStore = useAppStore()

const {proxy} = getCurrentInstance();
// 后端查询到的xml
const xml = ref("");
const viewOpen = ref(false);
const viewData = ref('');
const viewClass = ref('xml');
const dataExit = ref(false);
const deployId = ref("");
const category = ref(null);
const draftId = ref(null);
const formId = ref(null);

deployId.value = route.query && route.query.deployId;
category.value = route.query && route.query.category;
formId.value = route.query && route.query.formId;
formId.draftId = route.query && route.query.draftId;
modelerStore.setModules('formId', formId.value);
// //  查询流程xml
// if (deployId.value) {
//   getXmlData(deployId.value);
// }

/**
 *  自定义指令, 变量名为驼峰命名(vHighlight = v-highlight)
 *
 * Vue3 指令生命周期
 * created: 在绑定元素的 attribute 或事件监听器被应用之前调用
 * beforeMount: 当指令第一次绑定到元素并且在挂载父组件之前调用
 * mounted: 在绑定元素的父组件被挂载后调用
 * beforeUpdate: 在更新包含组件的 VNode 之前调用
 * updated: 在包含组件的 VNode 及其子组件的 VNode 更新后调用
 * beforeUnmount: 在卸载绑定元素的父组件之前调用
 * unmounted: 当指令与元素解除绑定且父组件已卸载时，只调用一次
 * @type {{mounted(*, *): void, updated(*, *): void}}
 */
const vHighlight = {
    mounted(el, binding) {
        const targets = el.querySelectorAll('code');
        let target;
        let i;
        for (i = 0; i < targets.length; i += 1) {
          target = targets[i];
          if (typeof binding.value === 'string') {
            target.textContent = binding.value;
            // 取消之前的高亮状态
            if (target.dataset.highlighted) {
              delete target.dataset.highlighted;
            }
            hljs.highlightElement(target);
          }
        }
      },
    updated(el, binding) {
      const targets = el.querySelectorAll('code');
      let target;
      let i;
      for (i = 0; i < targets.length; i += 1) {
        target = targets[i];
        if (typeof binding.value === 'string') {
          // 取消之前的高亮状态
          if (target.dataset.highlighted) {
            delete target.dataset.highlighted;
          }
          target.textContent = binding.value;
          hljs.highlightElement(target);
        }
      }
    }
}

/** xml 文件 */
function getXmlData(deployId) {
  // 发送请求，获取xml
  readXml(deployId).then(res => {
    xml.value = res.data;
  })
}

/** 保存xml */
async function save(data) {
    const params = {
        name: data.process.name,
        category: data.process.category,
        xml: data.xml,
        formId: formId.value
    };
    try {
      const res = await saveXml(params);
      if (res.code === 200) {
        proxy.$modal.msgSuccess(res.msg);
        const obj = {path: "/flowable/definition", query: {t: Date.now()}};
        proxy.$tab.closeOpenPage(obj);
        toggleSideBar();
      } else {
        this.$modal.msgError(res.msg);
      }
    } catch (error) {
      console.error(error);
    }
}


/** 指定流程办理人员列表 */
function getDataList() {
    userList().then(res => {
        modelerStore.setDataList("userList", markRaw(res.data));
    })
    roleList().then(res => {
        modelerStore.setDataList("roleList", markRaw(res.data));
    })
    expList().then(res => {
        modelerStore.setDataList("expList", markRaw(res.data));
    });
    deptList().then(res => {
        modelerStore.setDataList("deptList", markRaw(res.data));
    });
    postList().then(res => {
        modelerStore.setDataList("postList", markRaw(res.data));
    });
    formList().then(res => {
        res.data.forEach(item => {
          item.formId = item.formId.toString();
        });
        modelerStore.setDataList("formList", markRaw(res.data));
    });
    buttonList().then(res => {
        modelerStore.setDataList("buttonOption", markRaw(res.data));
    });

    // 如果是草稿箱进来的，就不需要再次请求xml
    const draftXml = modelerStore.getDraftXml;
    if (draftXml || deployId.value) {
      if (draftXml) {
        xml.value = draftXml;
        dataExit.value = true;
      } else {
        // 发送请求，获取xml
        readXml(deployId.value).then(res => {
          xml.value = res.data;
          dataExit.value = true;
        })
      }
    } else {
      dataExit.value = true;
    }
}

/** 展示xml */
function showXML(xmlStr) {
  viewOpen.value  = true;
  viewClass.value  = 'xml';
  viewData.value  = vkBeautify.xml(xmlStr);
}

/** 展示json */
function showJSON(jsonStr) {
  viewOpen.value  = true;
  viewClass.value  = 'json';
  viewData.value  = vkBeautify.json(jsonStr);
}

/** 复制代码成功 */
function copyTextSuccess() {
  proxy.$modal.msgSuccess("复制成功");
}

// 隐藏或显示侧边栏
function toggleSideBar() {
  appStore.toggleSideBar();
}

getDataList();
</script>
